package modele;

public class AFN implements Automata {

	StateSet set;
	StateSet initial_states;
	StateSet final_states;

	public AFN() {
		set = new StateSet();
		initial_states = new StateSet();
		final_states = new StateSet();
	}
	
	/**
	 * cf Automata.accept(String word)
	 */
	@Override
	public boolean accept(String word) {
		State current;
		Symbol symbol;
		for (State s : initial_states.getStateSet()) {
			System.out.println("-- " + s);
			current = s;
			for (int i = 0; i < word.length(); ++i) {
				System.out.print(" -" + word.charAt(i) + "-> ");
				symbol = new Letter(word.charAt(i));
				current = current.goStepByTransition(symbol);
				System.out.println(current);
				if (current == null)
					break;
			}
			if (isFinal(current))
				return true;
		}
		return false;
	}

	private boolean isFinal(State current) {
		return final_states.getStateSet().contains(current);
	}

	/**
	 * cf Automata.isEmpty()
	 */
	@Override
	public boolean isEmpty() {
		return set.getStateSet().isEmpty();
	}

	/**
	 * cf Automata.deterministic()
	 */
	@Override
	public AFN deterministic() {
		// TODO not implemented
		return null;
	}

	/**
	 * Display all the informations about the AFN.
	 */
	public void displayAFN() {
		System.out.println("\nStates : " + set.toString());
		System.out.println("Transitions :");
		for (State s : set.getStateSet())
			System.out.println(" - " + s.showTransitions());
		System.out.println("Initials : " + initial_states);
		System.out.println("Finals : " + final_states);
	}

	public StateSet getStates() {
		return set;
	}

	/**
	 * Add a state in the AFN
	 * @param s state to add
	 */
	public void addState(State s) {
		set.add(s);
	}
	
	/**
	 * Add a transition in the AFN
	 */
	public void addTransition(State start, Symbol transition, State end) {
		start.addTransition(end, transition);
	}

	public void setInitial(State s) {
		initial_states.add(s);
	}

	public void setFinal(State s) {
		final_states.add(s);
	}

}
